Chapter 2, Bytes, Ascii, Boolean, Logical, signed and unsigned ints 2.1.3 Data Sizes, page 32 (1E) or 38 (2E) CIS-Linux2:~/bando/chap2>p33x38.sh cat < p33x38.sh echo cat < p33x38.c echo echo gcc -m32 p33x38.c gcc -m32 p33x38.c echo a.out echo echo gcc p33x38.c gcc p33x38.c echo a.out #include main () { printf("size of char = %d\n", sizeof(char)); printf("size of short = %d\n", sizeof(short)); printf("size of int = %d\n", sizeof(int)); printf("size of long = %d\n", sizeof(long)); printf("size of long long = %d\n", sizeof(long long)); printf("size of float = %d\n", sizeof(float)); printf("size of double = %d\n", sizeof(double)); printf("size of long double = %d\n", sizeof(long double)); printf("size of char * = %d\n", sizeof(char *)); printf("size of short * = %d\n", sizeof(short *)); printf("size of int * = %d\n", sizeof(int *)); printf("size of long * = %d\n", sizeof(long *)); printf("size of long long * = %d\n", sizeof(long long *)); printf("size of float * = %d\n", sizeof(float *)); printf("size of double * = %d\n", sizeof(double *)); printf("size of long double * = %d\n", sizeof(long double *)); } gcc -m32 p33x38.c size of char = 1 size of short = 2 size of int = 4 size of long = 4 size of long long = 8 size of float = 4 size of double = 8 size of long double = 12 size of char * = 4 size of short * = 4 size of int * = 4 size of long * = 4 size of long long * = 4 size of float * = 4 size of double * = 4 size of long double * = 4 gcc p33x38.c size of char = 1 size of short = 2 size of int = 4 size of long = 8 size of long long = 8 size of float = 4 size of double = 8 size of long double = 16 size of char * = 8 size of short * = 8 size of int * = 8 size of long * = 8 size of long long * = 8 size of float * = 8 size of double * = 8 size of long double * = 8 CIS-Linux2:~/bando/chap2> 2.14 Addresses and byte ordering 1. Big endian vs little endian CIS-Linux2:~/bando/chap2>p34x39.sh echo cat p34x39.sh echo cat p34.data echo echo hexdump p34.data as 8-bit bytes hexdump -e '16/1 "%02x " "\n"' p34.data echo echo hexdump p34.data as 16-bit Intel "words" hexdump -e '8/2 "%02x " "\n"' p34.data echo echo hexdump p34.data as 32-bit Intel "doubles" hexdump -e '4/4 "%02x " "\n"' p34.data echo echo hexdump p34.data as 64-bit Intel "quads" hexdump -e '2/8 "%02x " "\n"' p34.data echo 12345678IJKLMNO hexdump p34.data as 8-bit bytes 31 32 33 34 35 36 37 38 49 4a 4b 4c 4d 4e 4f 0a hexdump p34.data as 16-bit Intel words 3231 3433 3635 3837 4a49 4c4b 4e4d a4f hexdump p34.data as 32-bit Intel doubles 34333231 38373635 4c4b4a49 a4f4e4d hexdump p34.data as 64-bit Intel quads 3837363534333231 a4f4e4d4c4b4a49 CIS-Linux2:~/bando/chap2> 2. Big endian vs little endian, part 2 gambit:~/bando/chap2>./p35.sh unix> more p35.c main() { short s; long l; long long ll; s=0x0123; l=0x01234567; ll=0x0123456789abcdefLL; } unix> gcc -S p35.c; more p35.s .file "p35.c" .text .globl main .type main, @function main: leal 4(%esp), %ecx andl $-16, %esp pushl -4(%ecx) pushl %ebp movl %esp, %ebp pushl %ecx subl $20, %esp movw $291, -22(%ebp) movl $19088743, -20(%ebp) movl $-1985229329, -16(%ebp) movl $19088743, -12(%ebp) addl $20, %esp popl %ecx popl %ebp leal -4(%ecx), %esp ret .size main, .-main .ident "GCC: (GNU) 4.1.2 20070502 (Red Hat 4.1.2-12)" .section .note.GNU-stack,"",@progbits unix> gcc -c p35.c; objdump -d p35.o p35.o: file format elf32-i386 Disassembly of section .text: 00000000
: 0: 8d 4c 24 04 lea 0x4(%esp),%ecx 4: 83 e4 f0 and $0xfffffff0,%esp 7: ff 71 fc pushl 0xfffffffc(%ecx) a: 55 push %ebp b: 89 e5 mov %esp,%ebp d: 51 push %ecx e: 83 ec 14 sub $0x14,%esp 11: 66 c7 45 ea 23 01 movw $0x123,0xffffffea(%ebp) 17: c7 45 ec 67 45 23 01 movl $0x1234567,0xffffffec(%ebp) 1e: c7 45 f0 ef cd ab 89 movl $0x89abcdef,0xfffffff0(%ebp) 25: c7 45 f4 67 45 23 01 movl $0x1234567,0xfffffff4(%ebp) 2c: 83 c4 14 add $0x14,%esp 2f: 59 pop %ecx 30: 5d pop %ebp 31: 8d 61 fc lea 0xfffffffc(%ecx),%esp 34: c3 ret unix> 3. Big endian vs little endian, part 3 CIS-Linux2:~/oct10>cat test1.c #include #define VALUE 0x030201 void show_bytes(unsigned char *, int); void show_int(int); void show_float(float); void show_pointer(void *); main() { int ival=VALUE; float fval = ival; int *pval = &ival; float *pval2 = &fval; show_int(ival); show_float(fval); show_pointer(pval); show_pointer(pval2); } void show_bytes(unsigned char *y, int len) { int i; for (i = 0; i < len; i++) printf(" %2.2x", y[i]); printf("\n"); } void show_int(int x) { show_bytes( (unsigned char *) &x, sizeof(int) ); } void show_float(float x) { show_bytes( (unsigned char *) &x, sizeof(float) ); } void show_pointer(void *x) { show_bytes( (unsigned char *) &x, sizeof(void *) ); } CIS-Linux2:~/oct10>gcc test1.c CIS-Linux2:~/oct10>a.out 01 02 03 00 40 80 40 48 7c e8 9b 26 ff 7f 00 00 78 e8 9b 26 ff 7f 00 00 CIS-Linux2:~/oct10>gcc -m32 test1.c CIS-Linux2:~/oct10>a.out 01 02 03 00 40 80 40 48 38 0d d1 ff 34 0d d1 ff CIS-Linux2:~/oct10> 2.15 ASCII (American Standard Code for Information Interchange unix> man ascii ASCII(7) Linux Programmerâs Manual ASCII(7) NAME ascii - the ASCII character set encoded in octal, decimal, and hexadec- imal DESCRIPTION ASCII is the American Standard Code for Information Interchange. It is a 7-bit code. Many 8-bit codes (such as ISO 8859-1, the Linux default character set) contain ASCII as their lower half. The international counterpart of ASCII is known as ISO 646. The following table contains the 128 ASCII characters. C program â\Xâ escapes are noted. Oct Dec Hex Char Oct Dec Hex Char ------------------------------------------------------------ 000 0 00 NUL â\0â 100 64 40 @ 001 1 01 SOH 101 65 41 A 002 2 02 STX 102 66 42 B 003 3 03 ETX 103 67 43 C 004 4 04 EOT 104 68 44 D 005 5 05 ENQ 105 69 45 E 006 6 06 ACK 106 70 46 F 007 7 07 BEL â\aâ 107 71 47 G 010 8 08 BS â\bâ 110 72 48 H 011 9 09 HT â\tâ 111 73 49 I 012 10 0A LF â\nâ 112 74 4A J 013 11 0B VT â\vâ 113 75 4B K 014 12 0C FF â\fâ 114 76 4C L 015 13 0D CR â\râ 115 77 4D M 016 14 0E SO 116 78 4E N 017 15 0F SI 117 79 4F O 020 16 10 DLE 120 80 50 P 021 17 11 DC1 121 81 51 Q ... 6. Practice Problems 2.5, 2.6, 2.7, 7. Boolean Algebra and C bit-level operators. NOT AND OR EXOR ~ | & | 0 1 | | 0 1 ^ | 0 1 --+--- --+------ --+------ --+------ 0 | 1 0 | 0 0 0 | 0 1 0 | 0 1 | | | | 1 | 0 1 | 0 1 1 | 1 1 1 | 1 0 C Binary Binary expression expression result C result ~0x41 ~[01000001] [10111110] 0xBE ~0x00 ~[00000000] [11111111] 0xFF 0x69 & 0x55 ~[01101001] & [01010101] [01000001] 0x41 0x69 | 0x55 ~[01101001] | [01010101] [01111101] 0x7D See practice problem 2.8, 2.10, 2.11, 2.12 8. All 16 Boolean functions and C bit-level expressions. ZERO AND 0 A & B A & ~B A B B B B 0 | 0 1 & | 0 1 | 0 1 A | 0 1 --+------ --+------- --+------- --+------- 0 | 0 0 0 | 0 0 0 | 0 0 0 | 0 0 A | A | A | A | 1 | 0 0 1 | 0 1 1 | 1 0 1 | 1 1 EXOR OR ~A & B B A ^ B A | B B B B B | 0 1 B | 0 1 ^ | 0 1 | | 0 1 --+------ --+------- --+------- --+------- 0 | 0 1 0 | 0 1 0 | 0 1 0 | 0 1 A | A | A | A | 1 | 0 0 1 | 0 1 1 | 1 0 1 | 1 1 NOR equal B->A ~(A|B) ~(A^B) ~B ~B|A B B B B ~ | 0 1 & | 0 1 | | 0 1 ^ | 0 1 --+------ --+------- --+------- --+------- 0 | 1 0 0 | 1 0 0 | 1 0 0 | 1 0 A | A | A | A | 1 | 0 0 1 | 0 1 1 | 1 0 1 | 1 1 NOT A A->B NAND ONE ~A ~A|B ~(A&B) 0xffff B B B B ~ | 0 1 & | 0 1 | | 0 1 ^ | 0 1 --+------ --+------- --+------- --+------- 0 | 1 1 0 | 1 1 0 | 1 1 0 | 1 1 A | A | A | A | 1 | 0 0 1 | 0 1 1 | 1 0 1 | 1 1 9. Logical operations in c. 1. || = OR, && = AND, ! = NOT 2. 0 represents False, any non-zero value represents True 3. Don't evaluate second argument if it won't effect result, so (a && 5/a) will never cause divison by zero. 4. Expression Result !0x41 0x00 !0x00 0x01 !!0x41 0x01 0x69 && 0x55 0x01 0x69 || 0x55 0x01 5. Practice problems 2.13 10. Shift operatins in C 1. x << k shifts x left k bits, filling the rightmost k bits with zeros. 2. x >> k shifts x right k bits, filling the leftmost bits with: a. unsigned numbers, fill with zeros. b. signed numbers, fill with a copy of the original leftmost bit (sign bit). 3. Practice Problem 2.15 11 Minimum and maximum values - extracted from /usr/include/limits.h /* These assume 8-bit `char's, 16-bit `short int's, and 32-bit `int's and `long int's. */ /* Number of bits in a `char'. */ # define CHAR_BIT 8 /* Minimum and maximum values a `signed char' can hold. */ # define SCHAR_MIN (-128) # define SCHAR_MAX 127 /* Maximum value an `unsigned char' can hold. (Minimum is 0.) */ # define UCHAR_MAX 255 /* Minimum and maximum values a `signed short int' can hold. */ # define SHRT_MIN (-32768) # define SHRT_MAX 32767 /* Maximum value an `unsigned short int' can hold. (Minimum is 0.) */ # define USHRT_MAX 65535 /* Minimum and maximum values a `signed int' can hold. */ # define INT_MIN (-INT_MAX - 1) # define INT_MAX 2147483647 /* Maximum value an `unsigned int' can hold. (Minimum is 0.) */ # define UINT_MAX 4294967295U /* Minimum and maximum values a `signed long int' can hold. */ # define LONG_MAX 2147483647L # define LONG_MIN (-LONG_MAX - 1L) 12. Signed and unsigned 4-bit arithmetic 1. 16-hour clock face labeled 0000 to 1111. 2. To add one, move hand clockwise one hour. 3. To subtract one, move hand counterclockwase one hour. 4. If you advance hand 16 hours, end up where you started. There must be an error point because X + 16 is not equal to x. Unsigned 4-bit Integers 2's Complement (2^n) 4-bit Integers error \ \ 0000=0 0000=0 \ o o 15=1111 o o 0001=1 -1=1111 o o 0001=1 ^ ^ 14=1110 o | o 0010=2 -2=1110 o | o 0010=2 | | 13=1101 o | o 0011=3 -3=1101 o | o 0011=3 | | | | 12=1100 o o o 0100=4 -4=1100 o o o 0100=4 11=1011 o o 0101=5 -5=1011 o o 0101=5 10=1010 o o 0110=6 -6=1010 o o 0110=6 9=1001 o o 0111=7 -7=1001 o o 0111=7 o o \ 1000=8 -8=1000 \ \ error 13. Signed magnitude and one's complement binary numbers 2's 1's signed binary unsigned complement complement magnitude 0000 0 0 0 0 0001 1 1 1 1 0010 2 2 2 2 0011 3 3 3 3 0100 4 4 4 4 0101 5 5 5 5 0110 6 6 6 6 0111 7 7 7 7 1000 8 -8 -7 -0 1001 9 -7 -6 -1 1010 10 -6 -5 -2 1011 11 -5 -4 -3 1100 12 -4 -3 -4 1101 13 -3 -2 -5 1110 14 -2 -1 -6 1111 15 -1 -0 -7